﻿using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Windows.Storage;
using System;
using Windows.Data.Xml.Dom;
using Windows.ApplicationModel;
using Windows.Devices.Geolocation;

namespace Beyondsoft.Tuanju.DataManager
{
    public class City
    {
        private List<Deal> deals = new List<Deal>();

        private static IDictionary<string, City> cities = new Dictionary<string, City>();

        private static ApplicationDataContainer localSettings = ApplicationData.Current.LocalSettings;

        public string CityIndex { set; get; }
        public string CityId { set; get; }
        public string CityName { set; get; }
        public string CityNamePY { set; get; }
        public string CityImage { set; get; }

        private City()
        {
        }

        public async static Task<City> GetCity(string name)
        {
            if (cities.Count() == 0)
            {
                cities = await GetCities();
            }

            if (cities.ContainsKey(name))
                return cities[name];
            else
                return cities.Values.First();
        }

        public async Task<IEnumerable<Deal>> GetDeals()
        {
            if (this.deals.Count == 0)
            {
                foreach (var p in Settings.Providers)
                {
                    this.deals.AddRange(await p.Value.GetDeals(this));
                }
            }

            return this.deals;
        }

        public async Task<IEnumerable<Deal>> GetDeals(string queryString)
        {
            if (this.deals.Count() == 0)
            {
                await GetDeals();
            }

            queryString = queryString.Trim();

            return this.deals.Where(
                deal => ((!string.IsNullOrEmpty(deal.Description) && deal.Description.Contains(queryString))
                        || (!string.IsNullOrEmpty(deal.Title) && deal.Title.Contains(queryString))
                        || (!string.IsNullOrEmpty(deal.ShortTitle) && deal.ShortTitle.Contains(queryString))));
        }

        public async Task<IEnumerable<Deal>> GetDeals(Category category)
        {
            if (this.deals.Count() == 0)
            {
                await GetDeals();
            }

            return this.deals.Where(deal => deal.Category == category);
        }

        public async Task<IEnumerable<Deal>> GetRecommends(int count)
        {
            if (this.deals.Count() == 0)
            {
                await GetDeals();
            }

            var providers = Settings.Providers;
            int length = providers.Count();

            List<Deal> result = new List<Deal>();

            int number = count / length + 1;

            foreach (var p in Settings.Providers)
            {
                var deals = await p.Value.GetRecommends(this, number);
                result.AddRange(deals);
            }

            return result;
        }

        public async Task<Deal> GetDeal(string dealId)
        {
            if (this.deals.Count() == 0)
            {
                await GetDeals();
            }

            return this.deals.FirstOrDefault(deal => deal.Gid == dealId);
        }

        public static City DefaultCity
        {
            get
            {
                var cityKey = localSettings.Values["defaultCity"] as string;

                if (cityKey == null)
                {
                    localSettings.Values["defaultCity"] = cities.FirstOrDefault().Key;
                    cityKey = localSettings.Values["defaultCity"] as string;
                }

                return cities[cityKey];
            }
            set
            {
                localSettings.Values["defaultCity"] = value.CityName;
            }
        }

        public static async Task<IDictionary<string, City>> GetCities()
        {
            if (cities.Count > 0)
            {
                return cities;
            }

            StorageFolder storageFolder = await Package.Current.InstalledLocation.GetFolderAsync("Beyondsoft.Tuanju.DataManager");
            StorageFolder dataFolder = await storageFolder.GetFolderAsync("Configuration");

            var cityFile = await dataFolder.GetFileAsync("Cities.xml");

            XmlDocument xdoc = await XmlDocument.LoadFromFileAsync(cityFile);

            var cityNodes = xdoc.SelectNodes("cities/city");

            foreach (var node in cityNodes)
            {
                string cityIndex = node.SelectSingleNode("Index").InnerText;
                string cityName = node.SelectSingleNode("Name").InnerText;
                string cityNamePY = node.SelectSingleNode("ENName").InnerText;
                string cityId = node.SelectSingleNode("Id").InnerText;
                string cityImage = node.SelectSingleNode("Image").InnerText;

                cities.Add(cityName, new City() { CityIndex = cityIndex, CityId = cityId, CityName = cityName, CityNamePY = cityNamePY, CityImage = cityImage });
            }

            return cities;
        }

        public static async Task<City> GetCity()
        {
            if (DefaultCity != null)
            {
                return DefaultCity;
            }

            Geolocator locator = new Geolocator();

            if (locator.LocationStatus == PositionStatus.Disabled)
            {
                return await GetCity(string.Empty);
            }
            
            Geoposition pos = await locator.GetGeopositionAsync();
            return await GetCity(pos.CivicAddress.City);
        }
    }
}
